/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.artic.jme3gui.client;

import com.artic.jme3gui.client.loader.AssetItem;
import com.artic.jme3gui.client.loader.AssetType;
import com.jme3.app.Application;
import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import com.jme3.font.BitmapFont;
import com.jme3.font.BitmapText;
import com.jme3.input.FlyByCamera;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.RenderState;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.Spatial.CullHint;

public class GameState extends AbstractAppState {

    protected Node rootNode = new Node(ApplicationConstants.ROOT_NODE);
    protected Node guiNode = new Node(ApplicationConstants.GUI_NODE);
    protected BitmapText fpsText;
    protected BitmapText menuText;
    protected BitmapFont guiFont;
    protected FlyByCamera flyCam;
    private ApplicationClient game = null;
    private AppActionListener actionListener = new AppActionListener();

    public GameState(ApplicationClient game) {
        this.game = game;
    }

    private class AppActionListener implements ActionListener {

        public void onAction(String name, boolean value, float tpf) {
            if (!value) {
                return;
            }
            if (name.equals(ApplicationConstants.APPLICATION_EXIT)) {
                game.stop();
            } else if (name.equals(ApplicationConstants.APPLICATION_MEMORY)) {
                game.loadMenu();
            }
        }
    }

    public void loadText() {
        guiFont = game.getAssetManager().loadFont("Interface/Fonts/Default.fnt");
        fpsText = new BitmapText(guiFont, false);
        fpsText.setSize(guiFont.getCharSet().getRenderedSize());
        fpsText.setLocalTranslation(0, fpsText.getLineHeight(), 0);
        fpsText.setText("Frames per second");
        guiNode.attachChild(fpsText);

        menuText = new BitmapText(guiFont, false);
        menuText.setSize(guiFont.getCharSet().getRenderedSize());
        menuText.setLocalTranslation(0, (game.getContext().getSettings().getHeight() / 2f) - (menuText.getLineHeight() / 2f), 0);
        menuText.setText("Press [M] to go back to the Menu");
        guiNode.attachChild(menuText);

    }

    @Override
    public void initialize(AppStateManager stateManager, Application app) {
        super.initialize(stateManager, app);
        System.out.println("init GameState...");
        // enable depth test and back-face culling for performance
        app.getRenderer().applyRenderState(RenderState.DEFAULT);

        guiNode.setQueueBucket(Bucket.Gui);
        guiNode.setCullHint(CullHint.Never);
        loadText();

        if (game.getInputManager() != null) {
            flyCam = new FlyByCamera(game.getCamera());
            flyCam.setMoveSpeed(1f);
            flyCam.registerWithInput(game.getInputManager());

            game.getInputManager().addMapping(ApplicationConstants.APPLICATION_EXIT, new KeyTrigger(KeyInput.KEY_ESCAPE));
            game.getInputManager().addMapping(ApplicationConstants.APPLICATION_MEMORY, new KeyTrigger(KeyInput.KEY_M));
        }

        for (AssetItem assetItem: ApplicationSingelton.getInstance(game).getAssetItems()) {
            if (assetItem != null && assetItem.getType() == AssetType.MODEL)
            {
                Spatial model = (Spatial) assetItem.getAsset();
                model.scale(0.05f, 0.05f, 0.05f);
                model.rotate(0.0f, -3.0f, 0.0f);
                model.setLocalTranslation(0.0f, -5.0f, -2.0f);
                rootNode.attachChild(model);
            }
        }

        // You must add a light to make the model visible
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));
        rootNode.addLight(sun);

    }

    @Override
    public void update(float tpf) {
        super.update(tpf);

        int fps = (int) game.getTimer().getFrameRate();
        fpsText.setText("Frames per second: " + fps);

        // simple update and root node
        rootNode.updateLogicalState(tpf);
        guiNode.updateLogicalState(tpf);
        rootNode.updateGeometricState();
        guiNode.updateGeometricState();
    }

    public void stateAttached(AppStateManager stateManager) {
        game.getInputManager().addListener(actionListener, ApplicationConstants.APPLICATION_EXIT, ApplicationConstants.APPLICATION_CAMERAPOS, ApplicationConstants.APPLICATION_MEMORY);

        if (flyCam != null) {
            flyCam.setEnabled(true);
        }

        game.getViewPort().attachScene(rootNode);
        game.getGUIViewPort().attachScene(guiNode);
    }

    public void stateDetached(AppStateManager stateManager) {
        game.getInputManager().removeListener(actionListener);
        if (flyCam != null) {
            flyCam.setEnabled(false);
        }

        game.getViewPort().detachScene(rootNode);
        game.getGUIViewPort().detachScene(guiNode);
    }

    public void render(RenderManager rm) {
    }
}
